Implemented N3194 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@120458 91177308-0d34-0410-b5e6-96231b3b80d8 
diff --git a/include/future b/include/future index f51ccb9..73a6391 100644 --- a/include/future +++ b/include/future 
@@ -156,6 +156,7 @@  ~future();  future& operator=(const future& rhs) = delete;  future& operator=(future&&); + shared_future<R> share() &&;    // retrieving the value  R get(); @@ -182,6 +183,7 @@  ~future();  future& operator=(const future& rhs) = delete;  future& operator=(future&&); + shared_future<R&> share() &&;    // retrieving the value  R& get(); @@ -208,6 +210,7 @@  ~future();  future& operator=(const future& rhs) = delete;  future& operator=(future&&); + shared_future<void> share() &&;    // retrieving the value  void get(); @@ -305,81 +308,6 @@  wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;  };   -template <class R> -class atomic_future -{ -public: - atomic_future(); - atomic_future(const atomic_future& rhs); - atomic_future(future<R>&&); - ~atomic_future(); - atomic_future& operator=(const atomic_future& rhs); - - // retrieving the value - const R& get() const; - - // functions to check state - bool valid() const; - - void wait() const; - template <class Rep, class Period> - future_status - wait_for(const chrono::duration<Rep, Period>& rel_time) const; - template <class Clock, class Duration> - future_status - wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; -}; - -template <class R> -class atomic_future<R&> -{ -public: - atomic_future(); - atomic_future(const atomic_future& rhs); - atomic_future(future<R>&&); - ~atomic_future(); - atomic_future& operator=(const atomic_future& rhs); - - // retrieving the value - R& get() const; - - // functions to check state - bool valid() const; - - void wait() const; - template <class Rep, class Period> - future_status - wait_for(const chrono::duration<Rep, Period>& rel_time) const; - template <class Clock, class Duration> - future_status - wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; -}; - -template <> -class atomic_future<void> -{ -public: - atomic_future(); - atomic_future(const atomic_future& rhs); - atomic_future(future<R>&&); - ~atomic_future(); - atomic_future& operator=(const atomic_future& rhs); - - // retrieving the value - void get() const; - - // functions to check state - bool valid() const; - - void wait() const; - template <class Rep, class Period> - future_status - wait_for(const chrono::duration<Rep, Period>& rel_time) const; - template <class Clock, class Duration> - future_status - wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; -}; -  template <class F, class... Args>  future<typename result_of<F(Args...)>::type>  async(F&& f, Args&&... args); @@ -413,7 +341,7 @@  packaged_task& operator=(packaged_task&& other);  void swap(packaged_task& other);   - explicit operator bool() const; + bool valid() const;    // result retrieval  future<R> get_future(); @@ -986,6 +914,7 @@  public:  #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES  ~future(); + shared_future<_R> share();    // retrieving the value  _R get(); @@ -1083,6 +1012,7 @@  public:  #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES  ~future(); + shared_future<_R&> share();    // retrieving the value  _R& get(); @@ -1175,6 +1105,7 @@  public:  #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES  ~future(); + shared_future<void> share();    // retrieving the value  void get(); @@ -1893,8 +1824,7 @@  }    _LIBCPP_INLINE_VISIBILITY - //explicit - operator bool() const {return __p_.__state_ != nullptr;} + bool valid() const {return __p_.__state_ != nullptr;}    // result retrieval  _LIBCPP_INLINE_VISIBILITY @@ -1956,7 +1886,7 @@  packaged_task<_R(_ArgTypes...)>::reset()  {  #ifndef _LIBCPP_NO_EXCEPTIONS - if (!(*this)) + if (!valid())  throw future_error(make_error_code(future_errc::no_state));  #endif // _LIBCPP_NO_EXCEPTIONS  __p_ = promise<result_type>(); @@ -2009,8 +1939,7 @@  }    _LIBCPP_INLINE_VISIBILITY - //explicit - operator bool() const {return __p_.__state_ != nullptr;} + bool valid() const {return __p_.__state_ != nullptr;}    // result retrieval  _LIBCPP_INLINE_VISIBILITY @@ -2074,7 +2003,7 @@  packaged_task<void(_ArgTypes...)>::reset()  {  #ifndef _LIBCPP_NO_EXCEPTIONS - if (!(*this)) + if (!valid())  throw future_error(make_error_code(future_errc::no_state));  #endif // _LIBCPP_NO_EXCEPTIONS  __p_ = promise<result_type>(); @@ -2352,222 +2281,27 @@  __x.swap(__y);  }   -// atomic_future -  template <class _R> -class _LIBCPP_VISIBLE atomic_future +inline _LIBCPP_INLINE_VISIBILITY +shared_future<_R> +future<_R>::share()  { - __assoc_state<_R>* __state_; - mutable mutex __mut_; - -public: - _LIBCPP_INLINE_VISIBILITY - atomic_future() : __state_(nullptr) {} - _LIBCPP_INLINE_VISIBILITY - atomic_future(const atomic_future& __rhs) : __state_(__rhs.__state_) - {if (__state_) __state_->__add_shared();} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY - atomic_future(future<_R>&& __f) : __state_(__f.__state_) - {__f.__state_ = nullptr;} -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - ~atomic_future(); - atomic_future& operator=(const atomic_future& __rhs); - - // retrieving the value - _LIBCPP_INLINE_VISIBILITY - const _R& get() const {return __state_->copy();} - - void swap(atomic_future& __rhs); - - // functions to check state - _LIBCPP_INLINE_VISIBILITY - bool valid() const {return __state_ != nullptr;} - - _LIBCPP_INLINE_VISIBILITY - void wait() const {__state_->wait();} - template <class _Rep, class _Period> - _LIBCPP_INLINE_VISIBILITY - future_status - wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const - {return __state_->wait_for(__rel_time);} - template <class _Clock, class _Duration> - _LIBCPP_INLINE_VISIBILITY - future_status - wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const - {return __state_->wait_until(__abs_time);} -}; - -template <class _R> -atomic_future<_R>::~atomic_future() -{ - if (__state_) - __state_->__release_shared(); + return shared_future<_R>(_STD::move(*this));  }    template <class _R> -atomic_future<_R>& -atomic_future<_R>::operator=(const atomic_future& __rhs) -{ - if (this != &__rhs) - { - unique_lock<mutex> __this(__mut_, defer_lock); - unique_lock<mutex> __that(__rhs.__mut_, defer_lock); - _STD::lock(__this, __that); - if (__rhs.__state_) - __rhs.__state_->__add_shared(); - if (__state_) - __state_->__release_shared(); - __state_ = __rhs.__state_; - } - return *this; -} - -template <class _R> -void -atomic_future<_R>::swap(atomic_future& __rhs) -{ - if (this != &__rhs) - { - unique_lock<mutex> __this(__mut_, defer_lock); - unique_lock<mutex> __that(__rhs.__mut_, defer_lock); - _STD::lock(__this, __that); - _STD::swap(__state_, __rhs.__state_); - } -} - -template <class _R> -class _LIBCPP_VISIBLE atomic_future<_R&> -{ - __assoc_state<_R&>* __state_; - mutable mutex __mut_; - -public: - _LIBCPP_INLINE_VISIBILITY - atomic_future() : __state_(nullptr) {} - _LIBCPP_INLINE_VISIBILITY - atomic_future(const atomic_future& __rhs) : __state_(__rhs.__state_) - {if (__state_) __state_->__add_shared();} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY - atomic_future(future<_R&>&& __f) : __state_(__f.__state_) - {__f.__state_ = nullptr;} -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - ~atomic_future(); - atomic_future& operator=(const atomic_future& __rhs); - - // retrieving the value - _LIBCPP_INLINE_VISIBILITY - _R& get() const {return __state_->copy();} - - void swap(atomic_future& __rhs); - - // functions to check state - _LIBCPP_INLINE_VISIBILITY - bool valid() const {return __state_ != nullptr;} - - _LIBCPP_INLINE_VISIBILITY - void wait() const {__state_->wait();} - template <class _Rep, class _Period> - _LIBCPP_INLINE_VISIBILITY - future_status - wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const - {return __state_->wait_for(__rel_time);} - template <class _Clock, class _Duration> - _LIBCPP_INLINE_VISIBILITY - future_status - wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const - {return __state_->wait_until(__abs_time);} -}; - -template <class _R> -atomic_future<_R&>::~atomic_future() -{ - if (__state_) - __state_->__release_shared(); -} - -template <class _R> -atomic_future<_R&>& -atomic_future<_R&>::operator=(const atomic_future& __rhs) -{ - if (this != &__rhs) - { - unique_lock<mutex> __this(__mut_, defer_lock); - unique_lock<mutex> __that(__rhs.__mut_, defer_lock); - _STD::lock(__this, __that); - if (__rhs.__state_) - __rhs.__state_->__add_shared(); - if (__state_) - __state_->__release_shared(); - __state_ = __rhs.__state_; - } - return *this; -} - -template <class _R> -void -atomic_future<_R&>::swap(atomic_future& __rhs) -{ - if (this != &__rhs) - { - unique_lock<mutex> __this(__mut_, defer_lock); - unique_lock<mutex> __that(__rhs.__mut_, defer_lock); - _STD::lock(__this, __that); - _STD::swap(__state_, __rhs.__state_); - } -} - -template <> -class _LIBCPP_VISIBLE atomic_future<void> -{ - __assoc_sub_state* __state_; - mutable mutex __mut_; - -public: - _LIBCPP_INLINE_VISIBILITY - atomic_future() : __state_(nullptr) {} - _LIBCPP_INLINE_VISIBILITY - atomic_future(const atomic_future& __rhs) : __state_(__rhs.__state_) - {if (__state_) __state_->__add_shared();} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY - atomic_future(future<void>&& __f) : __state_(__f.__state_) - {__f.__state_ = nullptr;} -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - ~atomic_future(); - atomic_future& operator=(const atomic_future& __rhs); - - // retrieving the value - _LIBCPP_INLINE_VISIBILITY - void get() const {__state_->copy();} - - void swap(atomic_future& __rhs); - - // functions to check state - _LIBCPP_INLINE_VISIBILITY - bool valid() const {return __state_ != nullptr;} - - _LIBCPP_INLINE_VISIBILITY - void wait() const {__state_->wait();} - template <class _Rep, class _Period> - _LIBCPP_INLINE_VISIBILITY - future_status - wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const - {return __state_->wait_for(__rel_time);} - template <class _Clock, class _Duration> - _LIBCPP_INLINE_VISIBILITY - future_status - wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const - {return __state_->wait_until(__abs_time);} -}; - -template <class _R>  inline _LIBCPP_INLINE_VISIBILITY -void -swap(atomic_future<_R>& __x, atomic_future<_R>& __y) +shared_future<_R&> +future<_R&>::share()  { - __x.swap(__y); + return shared_future<_R&>(_STD::move(*this)); +} + +inline _LIBCPP_INLINE_VISIBILITY +shared_future<void> +future<void>::share() +{ + return shared_future<void>(_STD::move(*this));  }    _LIBCPP_END_NAMESPACE_STD 
diff --git a/src/future.cpp b/src/future.cpp index 3022818..0b8628f 100644 --- a/src/future.cpp +++ b/src/future.cpp 
@@ -256,39 +256,4 @@  return *this;  }   -atomic_future<void>::~atomic_future() -{ - if (__state_) - __state_->__release_shared(); -} - -atomic_future<void>& -atomic_future<void>::operator=(const atomic_future& __rhs) -{ - if (this != &__rhs) - { - unique_lock<mutex> __this(__mut_, defer_lock); - unique_lock<mutex> __that(__rhs.__mut_, defer_lock); - _STD::lock(__this, __that); - if (__rhs.__state_) - __rhs.__state_->__add_shared(); - if (__state_) - __state_->__release_shared(); - __state_ = __rhs.__state_; - } - return *this; -} - -void -atomic_future<void>::swap(atomic_future& __rhs) -{ - if (this != &__rhs) - { - unique_lock<mutex> __this(__mut_, defer_lock); - unique_lock<mutex> __that(__rhs.__mut_, defer_lock); - _STD::lock(__this, __that); - _STD::swap(__state_, __rhs.__state_); - } -} -  _LIBCPP_END_NAMESPACE_STD 
diff --git a/test/thread/futures/futures.atomic_future/copy_assign.pass.cpp b/test/thread/futures/futures.atomic_future/copy_assign.pass.cpp deleted file mode 100644 index 8c3731c..0000000 --- a/test/thread/futures/futures.atomic_future/copy_assign.pass.cpp +++ /dev/null 
@@ -1,74 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// <future> - -// class atomic_future<R> - -// atomic_future& operator=(const atomic_future& rhs); - -#include <future> -#include <cassert> - -int main() -{ -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - { - typedef int T; - std::promise<T> p; - std::atomic_future<T> f0 = p.get_future(); - std::atomic_future<T> f; - f = f0; - assert(f0.valid()); - assert(f.valid()); - } - { - typedef int T; - std::atomic_future<T> f0; - std::atomic_future<T> f; - f = f0; - assert(!f0.valid()); - assert(!f.valid()); - } - { - typedef int& T; - std::promise<T> p; - std::atomic_future<T> f0 = p.get_future(); - std::atomic_future<T> f; - f = f0; - assert(f0.valid()); - assert(f.valid()); - } - { - typedef int& T; - std::atomic_future<T> f0; - std::atomic_future<T> f; - f = f0; - assert(!f0.valid()); - assert(!f.valid()); - } - { - typedef void T; - std::promise<T> p; - std::atomic_future<T> f0 = p.get_future(); - std::atomic_future<T> f; - f = f0; - assert(f0.valid()); - assert(f.valid()); - } - { - typedef void T; - std::atomic_future<T> f0; - std::atomic_future<T> f; - f = f0; - assert(!f0.valid()); - assert(!f.valid()); - } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -} 
diff --git a/test/thread/futures/futures.atomic_future/copy_ctor.pass.cpp b/test/thread/futures/futures.atomic_future/copy_ctor.pass.cpp deleted file mode 100644 index c982153..0000000 --- a/test/thread/futures/futures.atomic_future/copy_ctor.pass.cpp +++ /dev/null 
@@ -1,66 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// <future> - -// class atomic_future<R> - -// atomic_future(const atomic_future& rhs); - -#include <future> -#include <cassert> - -int main() -{ - { - typedef int T; - std::promise<T> p; - std::atomic_future<T> f0 = p.get_future(); - std::atomic_future<T> f = f0; - assert(f0.valid()); - assert(f.valid()); - } - { - typedef int T; - std::atomic_future<T> f0; - std::atomic_future<T> f = f0; - assert(!f0.valid()); - assert(!f.valid()); - } - { - typedef int& T; - std::promise<T> p; - std::atomic_future<T> f0 = p.get_future(); - std::atomic_future<T> f = f0; - assert(f0.valid()); - assert(f.valid()); - } - { - typedef int& T; - std::atomic_future<T> f0; - std::atomic_future<T> f = std::move(f0); - assert(!f0.valid()); - assert(!f.valid()); - } - { - typedef void T; - std::promise<T> p; - std::atomic_future<T> f0 = p.get_future(); - std::atomic_future<T> f = f0; - assert(f0.valid()); - assert(f.valid()); - } - { - typedef void T; - std::atomic_future<T> f0; - std::atomic_future<T> f = f0; - assert(!f0.valid()); - assert(!f.valid()); - } -} 
diff --git a/test/thread/futures/futures.atomic_future/default.pass.cpp b/test/thread/futures/futures.atomic_future/default.pass.cpp deleted file mode 100644 index 6eec60b..0000000 --- a/test/thread/futures/futures.atomic_future/default.pass.cpp +++ /dev/null 
@@ -1,33 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// <future> - -// class atomic_future<R> - -// atomic_future(); - -#include <future> -#include <cassert> - -int main() -{ - { - std::atomic_future<int> f; - assert(!f.valid()); - } - { - std::atomic_future<int&> f; - assert(!f.valid()); - } - { - std::atomic_future<void> f; - assert(!f.valid()); - } -} 
diff --git a/test/thread/futures/futures.atomic_future/dtor.pass.cpp b/test/thread/futures/futures.atomic_future/dtor.pass.cpp deleted file mode 100644 index ea4b542..0000000 --- a/test/thread/futures/futures.atomic_future/dtor.pass.cpp +++ /dev/null 
@@ -1,66 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// <future> - -// class atomic_future<R> - -// ~atomic_future(); - -#include <future> -#include <cassert> - -#include "../test_allocator.h" - -int main() -{ - assert(test_alloc_base::count == 0); - { - typedef int T; - std::atomic_future<T> f; - { - std::promise<T> p(std::allocator_arg, test_allocator<T>()); - assert(test_alloc_base::count == 1); - f = p.get_future(); - assert(test_alloc_base::count == 1); - assert(f.valid()); - } - assert(test_alloc_base::count == 1); - assert(f.valid()); - } - assert(test_alloc_base::count == 0); - { - typedef int& T; - std::atomic_future<T> f; - { - std::promise<T> p(std::allocator_arg, test_allocator<int>()); - assert(test_alloc_base::count == 1); - f = p.get_future(); - assert(test_alloc_base::count == 1); - assert(f.valid()); - } - assert(test_alloc_base::count == 1); - assert(f.valid()); - } - assert(test_alloc_base::count == 0); - { - typedef void T; - std::atomic_future<T> f; - { - std::promise<T> p(std::allocator_arg, test_allocator<T>()); - assert(test_alloc_base::count == 1); - f = p.get_future(); - assert(test_alloc_base::count == 1); - assert(f.valid()); - } - assert(test_alloc_base::count == 1); - assert(f.valid()); - } - assert(test_alloc_base::count == 0); -} 
diff --git a/test/thread/futures/futures.atomic_future/get.pass.cpp b/test/thread/futures/futures.atomic_future/get.pass.cpp deleted file mode 100644 index 5ca5408..0000000 --- a/test/thread/futures/futures.atomic_future/get.pass.cpp +++ /dev/null 
@@ -1,143 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// <future> - -// class atomic_future<R> - -// const R& atomic_future::get(); -// R& atomic_future<R&>::get(); -// void atomic_future<void>::get(); - -#include <future> -#include <cassert> - -void func1(std::promise<int>& p) -{ - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - p.set_value(3); -} - -void func2(std::promise<int>& p) -{ - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - p.set_exception(std::make_exception_ptr(3)); -} - -int j = 0; - -void func3(std::promise<int&>& p) -{ - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - j = 5; - p.set_value(j); -} - -void func4(std::promise<int&>& p) -{ - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - p.set_exception(std::make_exception_ptr(3.5)); -} - -void func5(std::promise<void>& p) -{ - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - p.set_value(); -} - -void func6(std::promise<void>& p) -{ - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - p.set_exception(std::make_exception_ptr('c')); -} - -int main() -{ - { - typedef int T; - { - std::promise<T> p; - std::atomic_future<T> f = p.get_future(); - std::thread(func1, std::move(p)).detach(); - assert(f.valid()); - assert(f.get() == 3); - assert(f.valid()); - } - { - std::promise<T> p; - std::atomic_future<T> f = p.get_future(); - std::thread(func2, std::move(p)).detach(); - try - { - assert(f.valid()); - assert(f.get() == 3); - assert(false); - } - catch (int i) - { - assert(i == 3); - } - assert(f.valid()); - } - } - { - typedef int& T; - { - std::promise<T> p; - std::atomic_future<T> f = p.get_future(); - std::thread(func3, std::move(p)).detach(); - assert(f.valid()); - assert(f.get() == 5); - assert(f.valid()); - } - { - std::promise<T> p; - std::atomic_future<T> f = p.get_future(); - std::thread(func4, std::move(p)).detach(); - try - { - assert(f.valid()); - assert(f.get() == 3); - assert(false); - } - catch (double i) - { - assert(i == 3.5); - } - assert(f.valid()); - } - } - { - typedef void T; - { - std::promise<T> p; - std::atomic_future<T> f = p.get_future(); - std::thread(func5, std::move(p)).detach(); - assert(f.valid()); - f.get(); - assert(f.valid()); - } - { - std::promise<T> p; - std::atomic_future<T> f = p.get_future(); - std::thread(func6, std::move(p)).detach(); - try - { - assert(f.valid()); - f.get(); - assert(false); - } - catch (char i) - { - assert(i == 'c'); - } - assert(f.valid()); - } - } -} 
diff --git a/test/thread/futures/futures.atomic_future/wait.pass.cpp b/test/thread/futures/futures.atomic_future/wait.pass.cpp deleted file mode 100644 index a2e5288..0000000 --- a/test/thread/futures/futures.atomic_future/wait.pass.cpp +++ /dev/null 
@@ -1,86 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// <future> - -// class atomic_future<R> - -// void wait() const; - -#include <future> -#include <cassert> - -void func1(std::promise<int>& p) -{ - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - p.set_value(3); -} - -int j = 0; - -void func3(std::promise<int&>& p) -{ - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - j = 5; - p.set_value(j); -} - -void func5(std::promise<void>& p) -{ - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - p.set_value(); -} - -int main() -{ - typedef std::chrono::high_resolution_clock Clock; - typedef std::chrono::duration<double, std::milli> ms; - { - typedef int T; - std::promise<T> p; - std::atomic_future<T> f = p.get_future(); - std::thread(func1, std::move(p)).detach(); - assert(f.valid()); - f.wait(); - assert(f.valid()); - Clock::time_point t0 = Clock::now(); - f.wait(); - Clock::time_point t1 = Clock::now(); - assert(f.valid()); - assert(t1-t0 < ms(5)); - } - { - typedef int& T; - std::promise<T> p; - std::atomic_future<T> f = p.get_future(); - std::thread(func3, std::move(p)).detach(); - assert(f.valid()); - f.wait(); - assert(f.valid()); - Clock::time_point t0 = Clock::now(); - f.wait(); - Clock::time_point t1 = Clock::now(); - assert(f.valid()); - assert(t1-t0 < ms(5)); - } - { - typedef void T; - std::promise<T> p; - std::atomic_future<T> f = p.get_future(); - std::thread(func5, std::move(p)).detach(); - assert(f.valid()); - f.wait(); - assert(f.valid()); - Clock::time_point t0 = Clock::now(); - f.wait(); - Clock::time_point t1 = Clock::now(); - assert(f.valid()); - assert(t1-t0 < ms(5)); - } -} 
diff --git a/test/thread/futures/futures.atomic_future/wait_for.pass.cpp b/test/thread/futures/futures.atomic_future/wait_for.pass.cpp deleted file mode 100644 index ce5407c..0000000 --- a/test/thread/futures/futures.atomic_future/wait_for.pass.cpp +++ /dev/null 
@@ -1,95 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// <future> - -// class atomic_future<R> - -// template <class Rep, class Period> -// future_status -// wait_for(const chrono::duration<Rep, Period>& rel_time) const; - -#include <future> -#include <cassert> - -typedef std::chrono::milliseconds ms; - -void func1(std::promise<int>& p) -{ - std::this_thread::sleep_for(ms(500)); - p.set_value(3); -} - -int j = 0; - -void func3(std::promise<int&>& p) -{ - std::this_thread::sleep_for(ms(500)); - j = 5; - p.set_value(j); -} - -void func5(std::promise<void>& p) -{ - std::this_thread::sleep_for(ms(500)); - p.set_value(); -} - -int main() -{ - typedef std::chrono::high_resolution_clock Clock; - { - typedef int T; - std::promise<T> p; - std::atomic_future<T> f = p.get_future(); - std::thread(func1, std::move(p)).detach(); - assert(f.valid()); - assert(f.wait_for(ms(300)) == std::future_status::timeout); - assert(f.valid()); - assert(f.wait_for(ms(300)) == std::future_status::ready); - assert(f.valid()); - Clock::time_point t0 = Clock::now(); - f.wait(); - Clock::time_point t1 = Clock::now(); - assert(f.valid()); - assert(t1-t0 < ms(5)); - } - { - typedef int& T; - std::promise<T> p; - std::atomic_future<T> f = p.get_future(); - std::thread(func3, std::move(p)).detach(); - assert(f.valid()); - assert(f.wait_for(ms(300)) == std::future_status::timeout); - assert(f.valid()); - assert(f.wait_for(ms(300)) == std::future_status::ready); - assert(f.valid()); - Clock::time_point t0 = Clock::now(); - f.wait(); - Clock::time_point t1 = Clock::now(); - assert(f.valid()); - assert(t1-t0 < ms(5)); - } - { - typedef void T; - std::promise<T> p; - std::atomic_future<T> f = p.get_future(); - std::thread(func5, std::move(p)).detach(); - assert(f.valid()); - assert(f.wait_for(ms(300)) == std::future_status::timeout); - assert(f.valid()); - assert(f.wait_for(ms(300)) == std::future_status::ready); - assert(f.valid()); - Clock::time_point t0 = Clock::now(); - f.wait(); - Clock::time_point t1 = Clock::now(); - assert(f.valid()); - assert(t1-t0 < ms(5)); - } -} 
diff --git a/test/thread/futures/futures.atomic_future/wait_until.pass.cpp b/test/thread/futures/futures.atomic_future/wait_until.pass.cpp deleted file mode 100644 index f6e3000..0000000 --- a/test/thread/futures/futures.atomic_future/wait_until.pass.cpp +++ /dev/null 
@@ -1,95 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// <future> - -// class atomic_future<R> - -// template <class Clock, class Duration> -// future_status -// wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; - -#include <future> -#include <cassert> - -typedef std::chrono::milliseconds ms; - -void func1(std::promise<int>& p) -{ - std::this_thread::sleep_for(ms(500)); - p.set_value(3); -} - -int j = 0; - -void func3(std::promise<int&>& p) -{ - std::this_thread::sleep_for(ms(500)); - j = 5; - p.set_value(j); -} - -void func5(std::promise<void>& p) -{ - std::this_thread::sleep_for(ms(500)); - p.set_value(); -} - -int main() -{ - typedef std::chrono::high_resolution_clock Clock; - { - typedef int T; - std::promise<T> p; - std::atomic_future<T> f = p.get_future(); - std::thread(func1, std::move(p)).detach(); - assert(f.valid()); - assert(f.wait_until(Clock::now() + ms(300)) == std::future_status::timeout); - assert(f.valid()); - assert(f.wait_until(Clock::now() + ms(300)) == std::future_status::ready); - assert(f.valid()); - Clock::time_point t0 = Clock::now(); - f.wait(); - Clock::time_point t1 = Clock::now(); - assert(f.valid()); - assert(t1-t0 < ms(5)); - } - { - typedef int& T; - std::promise<T> p; - std::atomic_future<T> f = p.get_future(); - std::thread(func3, std::move(p)).detach(); - assert(f.valid()); - assert(f.wait_until(Clock::now() + ms(300)) == std::future_status::timeout); - assert(f.valid()); - assert(f.wait_until(Clock::now() + ms(300)) == std::future_status::ready); - assert(f.valid()); - Clock::time_point t0 = Clock::now(); - f.wait(); - Clock::time_point t1 = Clock::now(); - assert(f.valid()); - assert(t1-t0 < ms(5)); - } - { - typedef void T; - std::promise<T> p; - std::atomic_future<T> f = p.get_future(); - std::thread(func5, std::move(p)).detach(); - assert(f.valid()); - assert(f.wait_until(Clock::now() + ms(300)) == std::future_status::timeout); - assert(f.valid()); - assert(f.wait_until(Clock::now() + ms(300)) == std::future_status::ready); - assert(f.valid()); - Clock::time_point t0 = Clock::now(); - f.wait(); - Clock::time_point t1 = Clock::now(); - assert(f.valid()); - assert(t1-t0 < ms(5)); - } -} 
diff --git a/test/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp b/test/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp index 339017b..70ea0ad 100644 --- a/test/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp +++ b/test/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp 
@@ -32,8 +32,8 @@  std::packaged_task<double(int, char)> p0(A(5));  std::packaged_task<double(int, char)> p;  p = p0; - assert(!p0); - assert(p); + assert(!p0.valid()); + assert(p.valid());  std::future<double> f = p.get_future();  p(3, 'a');  assert(f.get() == 105.0); @@ -42,7 +42,7 @@  std::packaged_task<double(int, char)> p0;  std::packaged_task<double(int, char)> p;  p = p0; - assert(!p0); - assert(!p); + assert(!p0.valid()); + assert(!p.valid());  }  } 
diff --git a/test/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp b/test/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp index f3696e5..a0f711a 100644 --- a/test/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp +++ b/test/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp 
@@ -32,8 +32,8 @@  std::packaged_task<double(int, char)> p0(A(5));  std::packaged_task<double(int, char)> p;  p = std::move(p0); - assert(!p0); - assert(p); + assert(!p0.valid()); + assert(p.valid());  std::future<double> f = p.get_future();  p(3, 'a');  assert(f.get() == 105.0); @@ -42,7 +42,7 @@  std::packaged_task<double(int, char)> p0;  std::packaged_task<double(int, char)> p;  p = std::move(p0); - assert(!p0); - assert(!p); + assert(!p0.valid()); + assert(!p.valid());  }  } 
diff --git a/test/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp b/test/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp index 4ea0a06..9884c49 100644 --- a/test/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp +++ b/test/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp 
@@ -31,8 +31,8 @@  {  std::packaged_task<double(int, char)> p0(A(5));  std::packaged_task<double(int, char)> p(p0); - assert(!p0); - assert(p); + assert(!p0.valid()); + assert(p.valid());  std::future<double> f = p.get_future();  p(3, 'a');  assert(f.get() == 105.0); @@ -40,7 +40,7 @@  {  std::packaged_task<double(int, char)> p0;  std::packaged_task<double(int, char)> p(p0); - assert(!p0); - assert(!p); + assert(!p0.valid()); + assert(!p.valid());  }  } 
diff --git a/test/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp b/test/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp index f78ec85..f53b26e 100644 --- a/test/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp +++ b/test/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp 
@@ -21,5 +21,5 @@  int main()  {  std::packaged_task<A(int, char)> p; - assert(!p); + assert(!p.valid());  } 
diff --git a/test/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp b/test/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp index f30cd7b..8ae5921 100644 --- a/test/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp +++ b/test/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp 
@@ -39,7 +39,7 @@  {  {  std::packaged_task<double(int, char)> p(A(5)); - assert(p); + assert(p.valid());  std::future<double> f = p.get_future();  p(3, 'a');  assert(f.get() == 105.0); @@ -51,7 +51,7 @@  {  A a(5);  std::packaged_task<double(int, char)> p(a); - assert(p); + assert(p.valid());  std::future<double> f = p.get_future();  p(3, 'a');  assert(f.get() == 105.0); 
diff --git a/test/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp b/test/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp index 2465d83..63042e8 100644 --- a/test/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp +++ b/test/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp 
@@ -43,7 +43,7 @@  std::packaged_task<double(int, char)> p(std::allocator_arg,  test_allocator<A>(), A(5));  assert(test_alloc_base::count > 0); - assert(p); + assert(p.valid());  std::future<double> f = p.get_future();  p(3, 'a');  assert(f.get() == 105.0); @@ -58,7 +58,7 @@  std::packaged_task<double(int, char)> p(std::allocator_arg,  test_allocator<A>(), a);  assert(test_alloc_base::count > 0); - assert(p); + assert(p.valid());  std::future<double> f = p.get_future();  p(3, 'a');  assert(f.get() == 105.0); 
diff --git a/test/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp b/test/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp index 62b515a..c668a67 100644 --- a/test/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp +++ b/test/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp 
@@ -31,8 +31,8 @@  {  std::packaged_task<double(int, char)> p0(A(5));  std::packaged_task<double(int, char)> p = std::move(p0); - assert(!p0); - assert(p); + assert(!p0.valid()); + assert(p.valid());  std::future<double> f = p.get_future();  p(3, 'a');  assert(f.get() == 105.0); @@ -40,7 +40,7 @@  {  std::packaged_task<double(int, char)> p0;  std::packaged_task<double(int, char)> p = std::move(p0); - assert(!p0); - assert(!p); + assert(!p0.valid()); + assert(!p.valid());  }  } 
diff --git a/test/thread/futures/futures.tas/futures.task.members/swap.pass.cpp b/test/thread/futures/futures.tas/futures.task.members/swap.pass.cpp index 11378a3..9f549aa 100644 --- a/test/thread/futures/futures.tas/futures.task.members/swap.pass.cpp +++ b/test/thread/futures/futures.tas/futures.task.members/swap.pass.cpp 
@@ -32,8 +32,8 @@  std::packaged_task<double(int, char)> p0(A(5));  std::packaged_task<double(int, char)> p;  p.swap(p0); - assert(!p0); - assert(p); + assert(!p0.valid()); + assert(p.valid());  std::future<double> f = p.get_future();  p(3, 'a');  assert(f.get() == 105.0); @@ -42,7 +42,7 @@  std::packaged_task<double(int, char)> p0;  std::packaged_task<double(int, char)> p;  p.swap(p0); - assert(!p0); - assert(!p); + assert(!p0.valid()); + assert(!p.valid());  }  } 
diff --git a/test/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp b/test/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp index ae99474..ef99f61 100644 --- a/test/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp +++ b/test/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp 
@@ -34,8 +34,8 @@  std::packaged_task<double(int, char)> p0(A(5));  std::packaged_task<double(int, char)> p;  swap(p, p0); - assert(!p0); - assert(p); + assert(!p0.valid()); + assert(p.valid());  std::future<double> f = p.get_future();  p(3, 'a');  assert(f.get() == 105.0); @@ -44,7 +44,7 @@  std::packaged_task<double(int, char)> p0;  std::packaged_task<double(int, char)> p;  swap(p, p0); - assert(!p0); - assert(!p); + assert(!p0.valid()); + assert(!p.valid());  }  } 
diff --git a/test/thread/futures/futures.atomic_future/ctor_future.pass.cpp b/test/thread/futures/futures.unique_future/share.pass.cpp similarity index 76% rename from test/thread/futures/futures.atomic_future/ctor_future.pass.cpp rename to test/thread/futures/futures.unique_future/share.pass.cpp index 443ff75..a19ce2e 100644 --- a/test/thread/futures/futures.atomic_future/ctor_future.pass.cpp +++ b/test/thread/futures/futures.unique_future/share.pass.cpp 
@@ -9,9 +9,9 @@    // <future>   -// class atomic_future<R> +// class future<R>   -// atomic_future(future<R>&& rhs); +// shared_future<R> share() &&;    #include <future>  #include <cassert> @@ -22,14 +22,14 @@  typedef int T;  std::promise<T> p;  std::future<T> f0 = p.get_future(); - std::atomic_future<T> f = std::move(f0); + std::shared_future<T> f = std::move(f0.share());  assert(!f0.valid());  assert(f.valid());  }  {  typedef int T;  std::future<T> f0; - std::atomic_future<T> f = std::move(f0); + std::shared_future<T> f = std::move(f0.share());  assert(!f0.valid());  assert(!f.valid());  } @@ -37,14 +37,14 @@  typedef int& T;  std::promise<T> p;  std::future<T> f0 = p.get_future(); - std::atomic_future<T> f = std::move(f0); + std::shared_future<T> f = std::move(f0.share());  assert(!f0.valid());  assert(f.valid());  }  {  typedef int& T;  std::future<T> f0; - std::atomic_future<T> f = std::move(f0); + std::shared_future<T> f = std::move(f0.share());  assert(!f0.valid());  assert(!f.valid());  } @@ -52,14 +52,14 @@  typedef void T;  std::promise<T> p;  std::future<T> f0 = p.get_future(); - std::atomic_future<T> f = std::move(f0); + std::shared_future<T> f = std::move(f0.share());  assert(!f0.valid());  assert(f.valid());  }  {  typedef void T;  std::future<T> f0; - std::atomic_future<T> f = std::move(f0); + std::shared_future<T> f = std::move(f0.share());  assert(!f0.valid());  assert(!f.valid());  }